<template>

  <!-- PC端 -->
  <PcChat class="pc-chat" :uploading="uploading" :chatArr="chatArr" :fileArr="fileArr"
    :currentUploadType="currentUploadType" :handleUpload="handleUpload" :imageAcceptType="imageAcceptType"
    :doucmentAcceptType="doucmentAcceptType" :handleSubmit="handleSubmit" :running="running" :handleStop="handleStop"
    :isCanSubmit="isCanSubmit" @handleInput="handleInput">
  </PcChat>

  <!-- 手机端 -->
  <MobileChat class="mobile-chat" :uploading="uploading" :chatArr="chatArr" :fileArr="fileArr"
    :currentUploadType="currentUploadType" :handleUpload="handleUpload" :imageAcceptType="imageAcceptType"
    :doucmentAcceptType="doucmentAcceptType" :handleSubmit="handleSubmit" :running="running" :handleStop="handleStop"
    :isCanSubmit="isCanSubmit" @handleInput="handleInput">
  </MobileChat>



</template>

<script setup lang="ts">
import { fetchEventSource } from "@microsoft/fetch-event-source";
import { apiConfigurable, apiUploadFile } from "@/request/api";
import { ref, onMounted, watch, computed } from "vue";

// import ElMessage from "element-plus";
import { ElMessage, ElMessageBox } from "element-plus";
// import type { UploadUserFile, UploadProps } from "element-plus";

import emitter from '@/utils/emitter'
import { chatItemVO, fileItemVO, uploadFileVO } from "@/interface/interface"

import PcChat from "@/components/PcChat.vue"
import MobileChat from "@/components/MobileChat.vue"



const uploading = ref(false);

const user = ref("abc-123");

const chatArr = ref<chatItemVO[]>([
  { role: "ai", content: "你好,欢迎使用AI智能客服!", type: "text", },
]);

const keyword = ref("");
const workflowRunId = ref("");
const taskId = ref("");
const running = ref(false);
const conversationId = ref("")


onMounted(() => { });

function handleInput(value: string) {
  keyword.value = value
}

const isCanSubmit = computed(() => {
  if (keyword.value.trim().length > 0) {
    return true
  } else {
    return false
  }

  // if (fileArr.value.length > 0 || keyword.value.trim().length > 0){
  //   return true
  // } else {
  //   return false
  // }
})




function handleSubmit() {


  if (!isCanSubmit.value) {
    return;
  }

  // const token = "app-zt3D0iTnLuZ7CzaDozWH654y";
  // app-d5v91rFchJGqddio7QHCXBE6
  // const token = "app-vRHhoRpzOnx1iYP61zKIyZzS";
  const token = "app-EBnDMIwsdUAkYmE0FhL1fZyk";


  if (keyword.value) {
    chatArr.value.push({
      role: "customer",
      content: keyword.value,
      type: "text",
    });
  }

  emitter.emit("scrollToBottom")
  emitter.emit("clearKeyword")


  for (let i = 0; i < fileArr.value.length; i++) {
    const item = fileArr.value[i];
    const content = currentUploadType.value === 'image' ? item.imgurl : item.documentInfo
    chatArr.value.push({
      role: "customer",
      content: content,
      type: currentUploadType.value,
    });
  }


  const data = {
    inputs: {},
    response_mode: "streaming",
    files: fileArr.value,
    // files:[],
    user: user.value,
    conversation_id: conversationId.value,
    query: keyword.value,
  };

  chatArr.value.push({ role: "ai", content: "", type: "text", status: "处理中..." });
  running.value = true;

  let eventdata = ""


  // const baseUrl = import.meta.env.VITE_BASE_URL || "/"
  // return
    const baseUrl = '/api'




  fetchEventSource(baseUrl + "/v1/chat-messages", {
    method: "POST",
    headers: {
      // "Content-Type":"multipart/form-data",
      "Content-Type": "application/json",
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify(data),
    // data:JSON.stringify(data),
    onmessage(event) {

      eventdata = event.data


      if (!event.data) {
        return
      }


      const res = JSON.parse(event.data);
      console.log("res", res)


      const content = chatArr.value[chatArr.value.length - 1].content;

      switch (res.event) {
        case "workflow_started":
          taskId.value = res.task_id;
          workflowRunId.value = res.workflow_run_id;
          conversationId.value = res.conversation_id
          fileArr.value = [];
          break;

        case "node_started":

          break;

        case "message":

          const regex = /(\!\[image\]\()(.*?)(\))/g;
          const imagesMatchArr = res.answer.match(regex);
          let imagesArr = []
          let htmlText = res.answer.replace(/\n/g, "<br/>");

          // 图片处理
          if (imagesMatchArr) {
            imagesArr = imagesMatchArr.map(item => {
              const imgurl = extractBetweenChars(item, '![image](', ')')
              // return `<img src='http://36.133.44.72:8081${imgurl}' style="width:98%;margin:10px auto;display:block" />`
              return `<img src='https://www.jkbnet.com:8899/api/${imgurl}' style="width:98%;margin:10px auto;display:block" />`

            })

            
            for (let i = 0; i < imagesMatchArr.length; i++) {
              const str = imagesMatchArr[i]
              const img = imagesArr[i]
              htmlText = htmlText.replace(str, img);
            }
          }




          chatArr.value[chatArr.value.length - 1].content = content + htmlText;
          chatArr.value[chatArr.value.length - 1].status = "正在回答中..."
          break;

        case "node_finished":

          break;

        case "workflow_finished":
          running.value = false;
          chatArr.value[chatArr.value.length - 1].status = "回答完成"
          break;
      }

      emitter.emit("scrollToBottom")
    },
    onclose() {
      console.log("close");
    },
    onerror(error) {
      console.log("error", error);
      throw error
    },
  });
}

function handleStop() {
  const url = `/v1/workflows/tasks/${taskId.value}/stop`;
  const data = {
    user: user.value,
  };
  apiConfigurable(url, data).then((res) => {
    if (res.status === 200) {
      running.value = false;
      chatArr.value[chatArr.value.length - 1].status = "已暂停"

    } else {
      ElMessage("操作失败");
    }
  });
}


function extractBetweenChars(str, startChar, endChar) {
  // const regex = new RegExp(`${startChar}(.*?)${endChar}`, 's'); // 使用非贪婪匹配
  const regex = new RegExp(/(\!\[image\]\()(.*?)(\))/, 's');

  const match = str.match(regex);
  return match ? match[2] : null; // 返回匹配到的内容，如果没有匹配到则返回null
}





const fileArr = ref<fileItemVO[]>([]);


const currentUploadType = ref("");
const imageAcceptType = ".JPG, .JPEG, .PNG, .GIF, .WEBP, .SVG";
const doucmentAcceptType = ".TXT, .MD, .MARKDOWN, .PDF, .HTML, .XLSX, .XLS, .DOCX, .CSV, .EML, .MSG, .PPTX, .PPT, .XML, .EPUB";



function handleUpload(file: uploadFileVO, type = "") {

  const data = {
    user: user.value,
    file: file.file,
  };
  uploading.value = true;

  apiUploadFile(data)
    .then(async (res) => {
      if (res.status === 201) {
        const fileItem: fileItemVO = {
          type,
          upload_file_id: res.data.id,
          transfer_method: "local_file",
        };
        if (type === "image") {
          fileItem.imgurl = (await fileToBase64(file.file)) as string;
        } else {
          fileItem.documentInfo = { name: res.data.name, size: res.data.size };
        }

        // 如果上传的文件类型发生了变化则清空文件列表
        if (currentUploadType.value !== type) {
          fileArr.value = []
          fileArr.value.push(fileItem);
          currentUploadType.value = type

        } else {
          fileArr.value.push(fileItem);
        }


      }
    })
    .finally(() => {
      uploading.value = false;
    });
}


function fileToBase64(file: File) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file); // 读取文件并返回数据URL
    reader.onload = () => resolve(reader.result); // 读取完成后，将结果（Base64编码的字符串）返回
    reader.onerror = (error) => reject(error); // 读取过程中发生错误时，返回错误
  });
}



</script>

<style>
.status-row {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  font-size: 10px;
  color: #909399;
}


@media (min-width: 1200px) {
  .mobile-chat {
    display: none;
  }

  .pc-chat {
    display: block;
  }
}


@media (min-width: 768px) and (max-width: 1199px) {
  .mobile-chat {
    display: none;
  }

  .pc-chat {
    display: block;
  }
}


@media (max-width: 767px) {
  .mobile-chat {
    display: flex;
  }

  .pc-chat {
    display: none;
  }
}
</style>